package com.google.code.p.restrpc.spring.naming;

import org.apache.commons.lang.StringUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import com.google.code.p.restrpc.spring.metadata.RpcAttributeSource;
import com.google.code.p.restrpc.spring.metadata.RpcMetadata;

public class MetadataNamingStrategy implements
                                   ServiceNamingStrategy,
                                   InitializingBean {
    
    /**
     * The <code>RpcAttributeSource</code> implementation to use for reading
     * metadata.
     */
    private RpcAttributeSource attributeSource;
    
    public MetadataNamingStrategy() {
    }
    
    public MetadataNamingStrategy(RpcAttributeSource attributeSource) {
        Assert.notNull(attributeSource,
                       "The 'attributeSource' must not be null");
        this.attributeSource = attributeSource;
    }
    
    public void setAttributeSource(RpcAttributeSource attributeSource) {
        Assert.notNull(attributeSource,
                       "The 'attributeSource' must not be null");
        this.attributeSource = attributeSource;
    }
    
    public void afterPropertiesSet() {
        if (this.attributeSource == null) {
            throw new IllegalArgumentException("Property 'attributeSource' is required");
        }
    }
    
    public String getServiceName(Object bean, String beanName) {
        Class managedClass = AopUtils.getTargetClass(bean);
        RpcMetadata metadata = this.attributeSource.getRpcMetadata(managedClass);
        
        // Check that an object name has been specified.
        return (metadata != null && StringUtils.isNotEmpty(metadata.getServiceName())) ? metadata.getServiceName()
                                                                          : beanName;
    }
    
    public String getServiceName(String serviceName, String beanName) {
        return StringUtils.isNotEmpty(serviceName) ? serviceName : beanName;
    }
}
